/// 
/// MaDAson - Toolkit for Model Driven Software Development
/// 
/// Copyright [2006] Marcus Lankenau
/// 
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///  
///     http://www.apache.org/licenses/LICENSE-2.0
///  
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
/// 

using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Core;
using NUnit.Framework;

namespace Madason.MetaModel.Interfaces.Tests
{
	[TestFixture]
	public class TestImportXmi11Statemachine : TestImportXmi11Base
	{
		string xmiStatemachine =
			@"<XMI.content xmlns:UML=""href://org.omg/UML/1.3"">" +
			@"	<UML:Class xmi.id=""UMLClass.3"" name=""Product"" visibility=""public"" isSpecification=""false"" namespace=""UMLPackage.2"" isRoot=""false"" isLeaf=""false"" isAbstract=""false"" isActive=""false"">" +
			@"	  <UML:Namespace.ownedElement>" +
			@"		<UML:StateMachine xmi.id=""UMLStateMachine.4"" name=""StateMachine1"" visibility=""public"" isSpecification=""false"" context=""UMLClass.3"">" +
			@"		  <UML:StateMachine.top>" +
			@"			<UML:CompositeState xmi.id=""UMLCompositeState.5"" name=""TOP"" visibility=""public"" isSpecification=""false"" stateMachine=""UMLStateMachine.4"" isConcurrent=""false"">" +
			@"			  <UML:CompositeState.subvertex>" +
			@"				<UML:Pseudostate xmi.id=""UMLPseudostate.6"" name=""Initial1"" visibility=""public"" isSpecification=""false"" container=""UMLCompositeState.5"" outgoing=""UMLTransition.8"" kind=""initial""/>" +
			@"				<UML:SimpleState xmi.id=""UMLCompositeState.7"" name=""Created"" visibility=""public"" isSpecification=""false"" container=""UMLCompositeState.6"" incoming=""UMLTransition.12"">"+
			@"                <UML:State.entry>"+
			@"				    <UML:UninterpretedAction xmi.id=""UMLUninterpretedAction.9"" name=""EntryAction1"" visibility=""public"" isSpecification=""false"" isAsynchronous=""false""/>"+
			@"                </UML:State.entry>"+
			@"                <UML:State.exit>"+
			@"				    <UML:UninterpretedAction xmi.id=""UMLUninterpretedAction.11"" name=""ExitAction1"" visibility=""public"" isSpecification=""false"" isAsynchronous=""false""/>"+
			@"				  </UML:State.exit>"+
			@"              </UML:SimpleState>" +
			@"				<UML:FinalState xmi.id=""UMLFinalState.8"" name=""FinalState1"" visibility=""public"" isSpecification=""false"" container=""UMLCompositeState.5""/>"+
			@"              <UML:Pseudostate xmi.id=""UMLPseudostate.20"" name=""Choice1"" visibility=""public"" isSpecification=""false"" container=""UMLCompositeState.13"" outgoing=""UMLTransition.33 UMLTransition.34"" incoming=""UMLTransition.31"" kind=""branch""/>"+
			@"			  </UML:CompositeState.subvertex>" +
			@"			</UML:CompositeState>" +
			@"		  </UML:StateMachine.top>" +
			@"		  <UML:StateMachine.transitions>" +
			@"			<UML:Transition xmi.id=""UMLTransition.8"" name=""FirstTransition"" visibility=""public"" isSpecification=""false"" stateMachine=""UMLStateMachine.4"" source=""UMLPseudostate.6"" target=""UMLCompositeState.7"">" +
			@"			  <UML:Transition.guard>"+
			@"				<UML:Guard xmi.id=""X.37"" transition=""UMLTransition.8"">"+
			@"                <UML:Guard.expression>"+
			@"                  <UML:BooleanExpression xmi.id=""X.38"" body=""IntAttr &lt; 5""/>"+
			@"				  </UML:Guard.expression>"+
			@"				</UML:Guard>"+
			@"            </UML:Transition.guard>" +
			@"			  <UML:Transition.effect>" +
			@"				<UML:ActionSequence xmi.id=""X.9"">" +
			@"				  <UML:ActionSequence.action>" +
			@"					<UML:UninterpretedAction xmi.id=""UMLUninterpretedAction.10"" name=""Effect1"" visibility=""public"" isSpecification=""false"" isAsynchronous=""false""/>" +
			@"				  </UML:ActionSequence.action>" +
			@"				</UML:ActionSequence>" +
			@"			  </UML:Transition.effect>" +
			@"			  <UML:Transition.trigger>" +
			@"				<UML:CallEvent xmi.id=""UMLCallEvent.11"" name=""CallEvent1"" visibility=""public"" isSpecification=""false"" transition=""UMLTransition.8""/>" +
			@"			  </UML:Transition.trigger>" +
			@"			</UML:Transition>" +
			@"		  </UML:StateMachine.transitions>" +
			@"		</UML:StateMachine>" +
			@"	  </UML:Namespace.ownedElement>" +
			@"	</UML:Class>" +
			@"</XMI.content>";

		[Test]
		public void TestStatemachine()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];

			Assert.AreEqual(1, cls.StateMachines.Count);
			Assert.AreEqual("StateMachine1", cls.StateMachines[0].Name);
		}

		[Test]
		public void TestChildStates()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			Assert.AreEqual(4, sm.States.Count);
		}

		[Test]
		public void TestStateTypes()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			Assert.AreEqual(4, sm.States.Count);

			Assert.AreEqual(StateType.Initial, sm.States[0].StateType);
			Assert.AreEqual(StateType.Simple, sm.States[1].StateType);
			Assert.AreEqual(StateType.Final, sm.States[2].StateType);
			Assert.AreEqual(StateType.Branch, sm.States[3].StateType);			
		}

		[Test]
		public void TestTransition()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			State initial = sm.FindStateByID("UMLPseudostate.6");
			Assert.AreEqual(1, initial.Transitions.Count);
			Assert.AreEqual("FirstTransition", initial.Transitions[0].Name);

		}

		[Test]
		public void TestTransitionTarget()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			State initial = sm.FindStateByID("UMLPseudostate.6");
			Assert.AreEqual("IntAttr < 5", initial.Transitions[0].Guard);
		}

		[Test]
		public void TestTransitionGuard()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			State initial = sm.FindStateByID("UMLPseudostate.6");
			
		}

		[Test]
		public void TestTransitionTrigger()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			State initial = sm.FindStateByID("UMLPseudostate.6");
			
			Assert.AreEqual(1, initial.Transitions[0].Trigger.Count);			
			StateTransitionTrigger trigger = initial.Transitions[0].Trigger[0];
			Assert.AreEqual("UMLCallEvent.11", trigger.Id);
			Assert.AreEqual("CallEvent1", trigger.Name);
		}

		[Test]
		public void TestStateActions()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			State state = sm.FindStateByID("UMLCompositeState.7");
			Assert.AreEqual(1, state.EntryActions.Count);
			Assert.AreEqual(1, state.ExitActions.Count);

			Assert.AreEqual("EntryAction1", state.EntryActions[0].Name);
			Assert.AreEqual("ExitAction1", state.ExitActions[0].Name);
			Assert.AreEqual("UMLUninterpretedAction.9", state.EntryActions[0].Id);
			Assert.AreEqual("UMLUninterpretedAction.11", state.ExitActions[0].Id);
		}

		[Test]
		public void TestTransitionAction()
		{
			Model model = LoadModel(xmiStatemachine);
			Class cls = model.Classes[0];
			StateMachine sm = cls.StateMachines[0];

			State initial = sm.FindStateByID("UMLPseudostate.6");
			Assert.AreEqual(1, initial.Transitions[0].Actions.Count);
			Assert.AreEqual("Effect1", initial.Transitions[0].Actions[0].Name);
		}
	}
}
